"""
Pydantic V1 的错误类型

References:
    https://docs.pydantic.dev/1.10/usage/models/#error-handling
"""

from typing import (
    Dict,
    Type,
)

from utils.validator_utils.pydantic_x.errors.base import PydanticErrorBase
from utils.validator_utils.pydantic_x.version import PYDANTIC_V1

if PYDANTIC_V1:
    import pydantic.errors as pe

else:
    import pydantic.v1.errors as pe


class PydanticTypeError(PydanticErrorBase):
    """ Pydantic V1 的 类型错误类 """

    code_prefix = "type_error."


class PydanticValueError(PydanticErrorBase):
    """ Pydantic V1 的 值错误类 """

    code_prefix = "value_error."


class PydanticV1CustomErrorBase(pe.PydanticValueError, PydanticValueError):
    """ Pydantic V1 自定义错误基类 """


def get_v1_custom_code_2_error() -> Dict[str, Type[PydanticErrorBase]]:
    """ 获取 Pydantic V1 自定义错误编号 - 错误类 映射 """

    return {
        f"value_error.{cls.code}": cls
        for cls in PydanticV1CustomErrorBase.__subclasses__()
        if cls.code
    }


class PydanticV1BuiltInError:
    """ Pydantic V1 内置错误 """

    # -------------------- TypeError --------------------

    class CallableError(PydanticTypeError):
        code = "callable"
        msg_template = "{value} is not callable"
        msg_template_zh_cn = "{value} 是不可调用的"

    class ClassError(PydanticTypeError):
        code = "class"
        msg_template = "a class is expected"
        msg_template_zh_cn = "应当是一个类"

    class DataclassTypeError(PydanticTypeError):
        code = "dataclass"
        msg_template = "instance of {class_name}, tuple or dict expected"
        msg_template_zh_cn = "应为 {class_name} 的实例、元组或字典"

    class DequeError(PydanticTypeError):
        code = "deque"
        msg_template = "value is not a valid deque"
        msg_template_zh_cn = "数值不是有效的双向队列"

    class EnumError(PydanticTypeError):
        code = "enum_instance"
        msg_template = "{value} is not a valid Enum instance"
        msg_template_zh_cn = "{value} 不是一个有效的枚举实例"

    class FloatError(PydanticTypeError):
        code = "float"
        msg_template = "value is not a valid float"
        msg_template_zh_cn = "数值不是有效的小数"

    class FrozenSetError(PydanticTypeError):
        code = "frozenset"
        msg_template = "value is not a valid frozenset"
        msg_template_zh_cn = "数值不是有效的冻结集合"

    class FrozenSetMaxLengthError(PydanticTypeError):
        code = "frozenset.max_items"
        msg_template = "ensure this value has at most {limit_value} items"
        msg_template_zh_cn = "请确保该冻结集合最多有 {limit_value} 个元素"

    class FrozenSetMinLengthError(PydanticTypeError):
        code = "frozenset.min_items"
        msg_template = "ensure this value has at least {limit_value} items"
        msg_template_zh_cn = "请确保该冻结集合至少有 {limit_value} 个元素"

    class HashableError(PydanticTypeError):
        code = "hashable"
        msg_template = "value is not a valid hashable"
        msg_template_zh_cn = "数值不是有效的可哈希对象"

    class IntEnumError(PydanticTypeError):
        code = "int_enum_instance"
        msg_template = "{value} is not a valid IntEnum instance"
        msg_template_zh_cn = "{value} 不是一个有效的数字枚举实例"

    class IntegerError(PydanticTypeError):
        code = "integer"
        msg_template = "value is not a valid integer"
        msg_template_zh_cn = "数值不是有效的整数"

    class IterableError(PydanticTypeError):
        code = "iterable"
        msg_template = "value is not a valid iterable"
        msg_template_zh_cn = "数值不是有效的可迭代对象"

    class JsonTypeError(PydanticTypeError):
        code = "json"
        msg_template = "JSON object must be str, bytes or bytearray"
        msg_template_zh_cn = "JSON 对象必须是 str、bytes 或 bytearray 类型"

    class ListError(PydanticTypeError):
        code = "list"
        msg_template = "value is not a valid list"
        msg_template_zh_cn = "数值不是有效的列表"

    class ListMaxLengthError(PydanticTypeError):
        code = "list.max_items"
        msg_template = "ensure this value has at most {limit_value} items"
        msg_template_zh_cn = "请确保该列表最多有 {limit_value} 个元素"

    class ListMinLengthError(PydanticTypeError):
        code = "list.min_items"
        msg_template = "ensure this value has at least {limit_value} items"
        msg_template_zh_cn = "请确保该列表至少有 {limit_value} 个元素"

    class ListUniqueItemsError(PydanticTypeError):
        code = "list.unique_items"
        msg_template = "the list has duplicated items"
        msg_template_zh_cn = "列表中有重复的元素"

    class MissingError(PydanticTypeError):
        code = "missing"
        msg_template = "field required"
        msg_template_zh_cn = "字段是必填的"

    class NoneIsNotAllowedError(PydanticTypeError):
        code = "none.not_allowed"
        msg_template = "none is not an allowed value"
        msg_template_zh_cn = "不允许为 None"

    class NoneIsAllowedError(PydanticTypeError):
        code = "none.allowed"
        msg_template = "value is not none"
        msg_template_zh_cn = "值不是 None"

    class NotNoneError(PydanticTypeError):
        code = "not_none"
        msg_template = "value is not None"
        msg_template_zh_cn = "值不是 None"

    class PathNotExistsError(PydanticTypeError):
        code = "path.not_exists"
        msg_template = 'file or directory at path "{path}" does not exist'
        msg_template_zh_cn = "路径为 {path} 的文件或目录不存在"

    class PathNotAFileError(PydanticTypeError):
        code = "path.not_a_file"
        msg_template = 'path "{path}" does not point to a file'
        msg_template_zh_cn = "路径为 {path} 未指向文件"

    class PathNotADirectoryError(PydanticTypeError):
        code = "path.not_a_directory"
        msg_template = 'path "{path}" does not point to a directory'
        msg_template_zh_cn = "路径为 {path} 未指向目录"

    class PathError(PydanticTypeError):
        code = "path"
        msg_template = "value is not a valid path"
        msg_template_zh_cn = "数值不是有效的路径"

    class SequenceError(PydanticTypeError):
        code = "sequence"
        msg_template = "value is not a valid sequence"
        msg_template_zh_cn = "数值不是有效的序列"

    class SetError(PydanticTypeError):
        code = "set"
        msg_template = "value is not a valid set"
        msg_template_zh_cn = "数值不是有效的集合"

    class SetMaxLengthError(PydanticTypeError):
        code = "set.max_items"
        msg_template = "ensure this value has at most {limit_value} items"
        msg_template_zh_cn = "请确保该集合最多有 {limit_value} 个元素"

    class SetMinLengthError(PydanticTypeError):
        code = "set.min_items"
        msg_template = "ensure this value has at least {limit_value} items"
        msg_template_zh_cn = "请确保该集合至少有 {limit_value} 个元素"

    class StrError(PydanticTypeError):
        code = "str"
        msg_template = "str type expected"
        msg_template_zh_cn = "数值不是有效的字符串"

    class StrRegexError(PydanticTypeError):
        code = "str.regex"
        msg_template = 'string does not match regex "{pattern}"'
        msg_template_zh_cn = "数值不是有效的字符串"

    class SubclassError(PydanticTypeError):
        code = "subclass"
        msg_template = "subclass of {expected_class} expected"
        msg_template_zh_cn = "应当是 {expected_class} 的子类"

    class TupleError(PydanticTypeError):
        code = "tuple"
        msg_template = "value is not a valid tuple"
        msg_template_zh_cn = "字符串不符合正则表达式 {pattern}"

    class TupleLengthError(PydanticTypeError):
        code = "tuple.length"
        msg_template = "wrong tuple length {actual_length}, expected {expected_length}"
        msg_template_zh_cn = "元组长度错误，实际长度为 {actual_length}，期望长度为 {expected_length}"

    class UUIDError(PydanticTypeError):
        code = "uuid"
        msg_template = "value is not a valid uuid"
        msg_template_zh_cn = "数值不是有效的 UUID"

    class UUIDVersionError(PydanticTypeError):
        code = "uuid.version"
        msg_template = "uuid version {required_version} expected"
        msg_template_zh_cn = "UUID 版本 {required_version} 未符合预期"

    # -------------------- ValueError --------------------

    class AnyStrMaxLengthError(PydanticValueError):
        code = "any_str.max_length"
        msg_template = "ensure this value has at most {limit_value} characters"
        msg_template_zh_cn = "请确保这个值最多有 {limit_value} 个字符"

    class AnyStrMinLengthError(PydanticValueError):
        code = "any_str.min_length"
        msg_template = "ensure this value has at least {limit_value} characters"
        msg_template_zh_cn = "请确保这个值至少有 {limit_value} 个字符"

    class BoolError(PydanticValueError):
        code = "bool"
        msg_template = "value could not be parsed to a boolean"
        msg_template_zh_cn = "值无法解析为布尔值"

    class BytesError(PydanticValueError):
        code = "bool"
        msg_template = "byte type expected"
        msg_template_zh_cn = "预期为 byte 类型"

    class ColorError(PydanticValueError):
        code = "color"
        msg_template = "value is not a valid color: {reason}"
        msg_template_zh_cn = "该值不是一个有效的颜色: {reason}"

    class DateError(PydanticValueError):
        code = "date"
        msg_template = "invalid date format"
        msg_template_zh_cn = "无效的日期格式"

    class DateNotInTheFutureError(PydanticValueError):
        code = "date.not_in_the_future"
        msg_template = "date is not in the future"
        msg_template_zh_cn = "日期不是未来的日期"

    class DateNotInThePastError(PydanticValueError):
        code = "date.not_in_the_past"
        msg_template = "date is not in the past"
        msg_template_zh_cn = "日期不是过去的日期"

    class DateTimeError(PydanticValueError):
        code = "datetime"
        msg_template = "invalid datetime format"
        msg_template_zh_cn = "无效的日期时间格式"

    class DictError(PydanticValueError):
        code = "dict"
        msg_template = "value is not a valid dict"
        msg_template_zh_cn = "数值不是有效的字典"

    class DecimalError(PydanticValueError):
        code = "decimal"
        msg_template = "value is not a valid decimal"
        msg_template_zh_cn = "数值不是有效的十进制数"

    class DecimalIsNotFiniteError(PydanticValueError):
        code = "decimal.not_finite"
        msg_template = "value is not a valid decimal"
        msg_template_zh_cn = "数值不是有效的十进制数"

    class DecimalMaxDigitsError(PydanticValueError):
        code = "decimal.max_digits"
        msg_template = "ensure that there are no more than {max_digits} digits in total"
        msg_template_zh_cn = "请确保总共不超过 {max_digits} 位数字"

    class DecimalMaxPlacesError(PydanticValueError):
        code = "decimal.max_places"
        msg_template = "ensure that there are no more than {decimal_places} decimal places"
        msg_template_zh_cn = "请确保小数部分不超过 {decimal_places} 位"

    class DecimalWholeDigitsError(PydanticValueError):
        code = "decimal.whole_digits"
        msg_template = "ensure that there are no more than {whole_digits} digits before the decimal point"
        msg_template_zh_cn = "请确保小数点前不超过 {whole_digits} 位数字"

    class DurationError(PydanticValueError):
        code = "duration"
        msg_template = "invalid duration format"
        msg_template_zh_cn = "无效的持续时间格式"

    class EmailError(PydanticValueError):
        code = "email"
        msg_template = "value is not a valid email address"
        msg_template_zh_cn = "数值不是有效的邮箱地址"

    class EnumMemberError(PydanticValueError):
        code = "enum"
        msg_template = "value is not a valid enumeration member; permitted: {enum_values}:"  # EnumMemberError.__str__
        msg_template_zh_cn = "该数值不是有效的枚举成员；允许的值包括 {enum_values}"

    class ExtraError(PydanticValueError):
        code = "extra"
        msg_template = "extra fields not permitted"
        msg_template_zh_cn = "不允许额外字段"

    class JsonError(PydanticValueError):
        code = "json"
        msg_template = "Invalid JSON"
        msg_template_zh_cn = "无效的 JSON"

    class NumberNotFiniteError(PydanticValueError):
        code = "number.not_finite_number"
        msg_template = "ensure this value is a finite number"
        msg_template_zh_cn = "请确保该值是一个有限数"

    class NumberNotMultipleError(PydanticValueError):
        code = "number.not_multiple"
        msg_template = "ensure this value is a multiple of {multiple_of}"
        msg_template_zh_cn = "请确保该值是 {multiple_of} 的倍数"

    class NumberNotGeError(PydanticValueError):
        code = "number.not_ge"
        msg_template = "ensure this value is greater than or equal to {limit_value}"
        msg_template_zh_cn = "请确保该值大于等于 {limit_value}"

    class NumberNotGtError(PydanticValueError):
        code = "number.not_gt"
        msg_template = "ensure this value is greater than {limit_value}"
        msg_template_zh_cn = "请确保该值大于 {limit_value}"

    class NumberNotLeError(PydanticValueError):
        code = "number.not_le"
        msg_template = "ensure this value is less than or equal to {limit_value}"
        msg_template_zh_cn = "请确保该值小于等于 {limit_value}"

    class NumberNotLtError(PydanticValueError):
        code = "number.not_lt"
        msg_template = "ensure this value is less than {limit_value}"
        msg_template_zh_cn = "请确保该值小于 {limit_value}"

    class PatternError(PydanticValueError):
        code = "regex_pattern"
        msg_template = "Invalid regular expression"
        msg_template_zh_cn = "无效的正则表达式"

    class StrictBoolError(PydanticValueError):
        code = "strictbool"  # noqa: ignore spell
        msg_template = "value is not a valid boolean"
        msg_template_zh_cn = "值不是有效的布尔值"

    class TimeError(PydanticValueError):
        code = "time"
        msg_template = "invalid time format"
        msg_template_zh_cn = "无效的时间格式"

    class UrlSchemeError(PydanticValueError):
        code = "url.scheme"
        msg_template = "invalid or missing URL scheme"
        msg_template_zh_cn = "无效或缺失的 URL"

    class WrongConstantError(PydanticValueError):
        code = "const"
        msg_template = "unexpected value; permitted: {permitted}"  # WrongConstantError.__str__
        msg_template_zh_cn = "不符合预期的值，允许的值 {permitted}"
